package com.imay.live.view;

import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.imay.base.util.ViewUtil;
import com.imay.live.R;
import com.imay.live.adapter.SupperDekaronAdapter;

/**
 * Created by lzx on 2017/07/26 0026.
 */

public class SupperScrollView extends HorizontalScrollView {
    private Handler handler = new Handler();
    private ScrollOver scrollOver;
    private float lastx = 0;
    private float dx = 0;

    public void setScrollOver(ScrollOver scrollOver) {
        this.scrollOver = scrollOver;
    }

    public SupperScrollView(Context context) {
        super(context);
        init(context);
    }

    public SupperScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SupperScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SupperScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    void init(Context context) {
        final float ppi = getResources().getDisplayMetrics().density * 160.0f;
        mPhysicalCoeff = SensorManager.GRAVITY_EARTH // g (m/s^2)
                * 39.37f // inch/meter
                * ppi
                * 0.84f; // look and feel tuning
        mFlingFriction = ViewConfiguration.getScrollFriction();
    }

    public interface ScrollOver {
        void srollover();
    }

    LinearLayout linearLayout;
    View lastview;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        linearLayout = ((LinearLayout) getChildAt(0));
    }

    boolean isscrollto;

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        if (lastview != null && lastview instanceof TextView) {
            float lestx = getScrollX() - dx;
            if (lestx > 0) {
                if (lestx >= lastview.getMeasuredWidth()) {
                    if (scrollOver != null) {
                        deltaX = 0;
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                scrollTo((int) (dx), 0);
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        scrollOver.srollover();
                                    }
                                }, 10);
                                isscrollto = true;
                            }
                        }, 50);
                    }
                }

                if (isTouchEvent) {
                    int last = 0;
                    if (deltaX > 0) {
                        last = 1;
                    }
                    deltaX = deltaX / 3;
                    if (deltaX == 0) {
                        deltaX = last;
                    }
                } else {
                    if (!isscrollto) {
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                smoothScrollTo((int) (dx), 0);
                            }
                        }, 50);
                    }
                    isscrollto = true;
                }
            }
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

    final float leftscale = 0.2f;
    final float rightscale = 0.8f;

    public void setAntion(int visibility) {
        if (getChildCount() > 0 && linearLayout != null) {
            if (visibility != VISIBLE) {
                for (int i = 0; i < linearLayout.getChildCount(); i++) {
                    if (linearLayout.getChildAt(i) instanceof WebpView) {
                        WebpView webpView = (WebpView) linearLayout.getChildAt(i);
                        webpView.setAntion(visibility);
                    }
                }
            } else {
                float newl = (l + ViewUtil.mScreemWidth - SupperDekaronAdapter.padding);
                float postion = (newl / (SupperDekaronAdapter.w + SupperDekaronAdapter.padding));
                float leftpostion = (l / (SupperDekaronAdapter.w + SupperDekaronAdapter.padding));
                if (postion > 1 && postion < linearLayout.getChildCount()) {
//                    float lpos = postion % 1;
//                    if (lpos < rightscale) {
//                    } else {
//                    }
                    float opos = leftpostion % 1;
                    if (opos > leftscale) {
                        leftpostion = leftpostion + (1 - leftscale);
                    }
                    for (int i = (int) leftpostion; i < (int) postion; i++) {
                        if (linearLayout.getChildAt(i) instanceof WebpView) {
                            WebpView webpView = (WebpView) linearLayout.getChildAt(i);
                            webpView.setAntion(visibility);
                        }
                    }
                }
            }
        }
    }

    int l;

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        this.l = l;
        change(l, VISIBLE);
    }

    private void change(int l, int visibility) {
        float newl = (l + ViewUtil.mScreemWidth - SupperDekaronAdapter.padding);
        float postion = (newl / (SupperDekaronAdapter.w + SupperDekaronAdapter.padding));
        if (postion > 1 && postion < linearLayout.getChildCount()) {
            final View rightview = linearLayout.getChildAt((int) postion);
//            float leftpostion = postion - SupperDekaronAdapter.sum;
            float leftpostion = (l / (SupperDekaronAdapter.w + SupperDekaronAdapter.padding));
            float opos = leftpostion % 1;
            float lpos = postion % 1;
            if (leftpostion >= 0 && leftpostion < linearLayout.getChildCount()) {
                final View endview = linearLayout.getChildAt((int) leftpostion);
                if (endview instanceof WebpView) {
                    WebpView endimageView = (WebpView) endview;
                    if (opos > leftscale) {
                        endimageView.setAntion(INVISIBLE);
                    } else {
                        endimageView.setAntion(visibility);
                    }
                }
            }
            if (rightview instanceof WebpView) {
                String url = (String) rightview.getTag(R.id.iv_supper_image);
                WebpView imageView = (WebpView) rightview;
                if (url != null) {
                    imageView.setTag(R.id.iv_supper_image, null);
                    imageView.setUri(url, imageView.getMeasuredWidth(), imageView.getMeasuredHeight());
                } else {
                    if (lpos < rightscale) {
                        imageView.setAntion(INVISIBLE);
                    } else {
                        imageView.setAntion(visibility);
                    }
                }
            }
        }
    }

    @Override
    public void fling(int velocityX) {
        if (velocityX <= 0 || lastview == null) {
            super.fling(velocityX);
            return;
        }
        double tox = getScrollX() + getSplineFlingDistance(velocityX);
        if (tox > dx) {
            double max = dx - getScrollX() + lastview.getMeasuredWidth() / 2;
            velocityX = (int) velocityfromdistance(max);//计算距离
            isscrollto = false;
        }
        super.fling(velocityX);
    }

    private double velocityfromdistance(double distance) {
        double exp = distance / (mFlingFriction * mPhysicalCoeff);
        return Math.exp(Math.log(exp) / (2.3582017 / 1.3582017)) * (mFlingFriction * mPhysicalCoeff) / INFLEXION;
    }

    private float mPhysicalCoeff;
    private float mFlingFriction;
    private static final float INFLEXION = 0.35f;

    private double getSplineFlingDistance(int velocity) {
        final double l = getSplineDeceleration(velocity);
        return mFlingFriction * mPhysicalCoeff * Math.exp(2.3582017 / 1.3582017 * l);
    }

    private double getSplineDeceleration(int velocity) {
        return Math.log(INFLEXION * Math.abs(velocity) / (mFlingFriction * mPhysicalCoeff));
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (lastview == null) {
            lastview = linearLayout.getChildAt(linearLayout.getChildCount() - 1);
            if (!(lastview instanceof TextView)) {
                lastview = null;
            } else {
                lastx = lastview.getX();
                dx = lastx - ViewUtil.mScreemWidth;
            }
            return super.onTouchEvent(ev);
        }
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            if (getScrollX() >= dx) {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        smoothScrollTo((int) (dx), 0);
                    }
                }, 50);
            }
        }
        return super.onTouchEvent(ev);
    }
}
